/* 
 * artist style definition
 *
 * Choi Jonghwan<saxboy@gmail.com>
 * 2006/04/23
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pattern.h"

PATTERN pattern_New(void)
{
	PATTERN p = NULL; 
	if ( (p=(PATTERN)malloc(sizeof(_PATTERN)))!=NULL)
	{
		memset(p, 0, sizeof(_PATTERN)); 
	}
	return p; 
}

PATTERN pattern_NewWithDefinition(const char *def)
{
	PATTERN p = NULL; 
	if ( (p = pattern_New())!=NULL)
	{
		if ( pattern_ImportDefinition(p, def) > 0 )
			return p;

	}
	return NULL; 
}

int pattern_Delete(PATTERN p)
{
	if ( p==NULL) return -1; 
	free(p); 
	return 1; 
}

int pattern_ImportDefinition(PATTERN p, const char *def)
{
	if (p==NULL) return -1; 
	if (def==NULL) return -1;

	/* eg.)  name { rel_note+length } 
	 *
	 * jazz_sax { 1Q 3Q 5Q 7Q }
	 *
	 * FIXME: 
	 *
	 * import chord-scale mappings?
	 * write real, detailed token analyzer here. 
	 *
	 */

	/* temporary... */
	{
		char *pat = NULL; 
		char *name = NULL; 
		char *tmp = strdup(def); 

		name = strtok( tmp, "{" ); 
		pat = strtok( NULL, "}" ); 


		strncpy( p->name, name, MAX_PATTERN_NAME_LEN ); 

		/* drum pattern starts with '-' */
		if ( name[0] == '-' )
		{
			p->b_is_drum_pattern = 1; 
			strncpy( p->drum_pattern, pat, 128); 

		}
		else
		{
			char *x = NULL; 

			p->b_is_drum_pattern = 0; 
			
			x = strtok( pat, " "); 
			while (x!=NULL)
			{

				/* parse basic element */
				{
					_PATTERN_ELEM _elem; 

					_elem.pos = x[0]-'0'; 

					/* FIXME: more note length definitions... */
					switch ( x[1] )
					{
						case 'D':
							if ( x[2] == 'E' )
								_elem.note_length = NOTE_DOTTED_EIGHTH; 
							break;

						case 'E':
							_elem.note_length = NOTE_EIGHTH; 
							break;
						case 'Q': 
							_elem.note_length = NOTE_QUARTER; 
							break;
						case 'H':
							_elem.note_length = NOTE_HALF; 
							break;
						case 'S':
							_elem.note_length = NOTE_SIXTEENTH; 
							break;
						default:
							printf("(%s:%d) FIXME: unsupported note length\n", __FILE__, __LINE__ ); 
							_elem.note_length = -1; 
							break;
					}

					pattern_AddElement(p, &_elem); 
				}
				
				x = strtok(NULL, " "); 
			}
		}


		if ( tmp!=NULL) free(tmp); 
	}

	/* now calculate sum of note length of the pattern */
	{
		int i=0; 

		p->pattern_length = 0; 

		for (i=0; i< p->elem_count; i++)
			p->pattern_length += p->elems[i].note_length; 
	}

	return 1; 

}



int pattern_AddElement(PATTERN p, PATTERN_ELEM elem)
{
	if ( p==NULL) return -1; 
	if ( elem==NULL) return -1; 

	p->elems[ p->elem_count ].pos = elem->pos; 
	p->elems[ p->elem_count ].note_length = elem->note_length; 
	p->elem_count++; 


	return 1;
}

/*
 * alter given pattern based on some creativity(huh?)
 */
int pattern_AddCreativity(PATTERN p)
{
	int i=0; 

	if ( p==NULL) return -1; 

	for (i=0; i< p->elem_count; i++)
	{
	}

	return 1; 
}

